package com.letfox.common.datasource;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.util.DruidPasswordCallback;

/**
 * 解密
 * 
 */
public class EncryptedPasswordCallback extends DruidPasswordCallback {

    private static final long serialVersionUID = 1L;

    private static Logger logger = LoggerFactory.getLogger(EncryptedPasswordCallback.class);

    /** 公钥文件路径 */
    private String publicKeyPath;

    private boolean isLoad;
    /** 密钥 */
    private String publicKey;
    
    public static void main(String[] args) throws Exception {
        String key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJqIGk8"
                + "oyPM3qIVcPmZb4CwcIblN3LzLj3jW9E1XwVfqycHHXz7T+6WCaKc0cmJL5G7aljhzgRXq992etRiSjpsCAwEAAQ==";
        String pwd = "I5q6N0P/UHikTrA7woUava2bWbj4h80dMVZm/+3myWGwTbkXHxA4NcnH4ddHk+pBmm1U8J2wblUiWmwA2u5S6Q==";
        String str = ConfigTools.decrypt(key, pwd);
        System.out.println(str);
    }

    public char[] getPassword() {
        return encryptedPassword();
    }

    private char[] encryptedPassword() {
        try {
            String password = getProperties().getProperty("password");
            if (null == password || 0 == password.length()) {
                return "".toCharArray();
            }
            String password2;
            /** 是否不解密，默认false，即：默认解密 */
            String isNotDecrypt = getProperties().getProperty("isNotDecrypt");
            if ("true".equals(isNotDecrypt)) {
                password2 = password;
            } else {
                String publicKey = getKeys();
                password2 = ConfigTools.decrypt(publicKey, password);
            }
            logger.debug("password decrypt successful! password=" + password2);
            return password2.toCharArray();
        } catch (Exception e) {
            logger.error("password decrypt exception! url is" + getUrl(), e);
            return "".toCharArray();
        }
    }
    
    public String getKeys() {
        if (isLoad) {
            return publicKey;
        }
        synchronized (this) {
            if (isLoad) {
                return publicKey;
            }
            if (StringUtils.isNotBlank(publicKeyPath)) {
                InputStream in = null;
                try {
                    in = new FileInputStream(absolutePath());
                    Properties ps = new Properties();
                    ps.load(in);
                    publicKey = ps.getProperty("publicKey");
                } catch (IOException e) {
                    logger.error("get publicKey error, path: " + publicKeyPath, e);
                } finally {
                    isLoad = true;
                    IOUtils.closeQuietly(in);
                }
            }
            return publicKey;
        }
    }

    private String absolutePath() {
        if ('/' == publicKeyPath.charAt(0)) {
            return publicKeyPath;
        }
        try {
            return ClassLoader.getSystemResource("").toURI().getPath() + publicKeyPath;
        } catch (URISyntaxException e) {
            logger.error("get absolutePath exception", e);
        }
        return publicKeyPath;
    }

    public String getPublicKeyPath() {
        return publicKeyPath;
    }

    public void setPublicKeyPath(String publicKeyPath) {
        this.publicKeyPath = publicKeyPath;
    }
}